#coding=utf-8
#LightCam 进程监控程序
#init by hfh 20150212

import multiprocessing,subprocess,threading
import socket,os,time,re,traceback,sys
from pysnmp.entity.rfc3413.oneliner import cmdgen
import lc_libs

def func(this):
	#agent_hostname=this['agent_hostname']
	Hostname=this['Hostname']
	DeviceName=this['DeviceName']
	IPADDR=this['IPADDR']
	PORT=int(this['PORT'])
	Community=str(this['Community'])
	Version=int(this['Version'])
	OID=this['OID']
	Interval=this['Interval']
	Schedule=this['Schedule']
	Holiday=this['Holiday']
	
	
	PortFlow={}
	#BaseOID="."+str(OID[1:])
	IndexOID=OID+".1."
	PortNameOID=OID+".2."
	BandWidthOID=OID+".5."
	InOctetsOID=OID+".10."
	OutOctetsOID=OID+".16."
	ThisTime=int(time.time())
	#comd="snmpwalk -m MIB -On -v 2c -c public %s %s" % (IPADDR,OID)
	#popen=subprocess.Popen(comd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
	errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().nextCmd(
		cmdgen.CommunityData('my-agent',Community,Version),
		cmdgen.UdpTransportTarget((IPADDR, PORT)),
		OID
	)
	#for i in varBinds:
	#	print "%s = %s" % (i[0][0],i[0][1])
	
	#exit(0)
	
	#for lines in popen.stdout.read().split('\n'):
	#	line=lines.strip("\r\n ")

	for lines in varBinds:

		thisoid=str(lines[0][0])
		thisvalue=str(lines[0][1])
		#初始化
		#thisline=line.split()
		Index=""
		try:
			#Index=thisline[0].split(".")[-1]
			Index=thisoid.split(".")[-1]
		except:
			print thisoid
		if IndexOID in thisoid:
			if Index not in PortFlow.keys():
				PortFlow[Index]={
					"DeviceName":DeviceName,
					"IPADDR":IPADDR,
					"PortName":0,
					"BandWidth":0,
					"LastInOctets":-1,
					"LastOutOctets":-1,
					"InOctets":-1,
					"OutOctets":-1,
					"InUse":0.0,
					"OutUse":0.0,
					"Time":ThisTime
				}
			else:
				PortFlow[Index]['Time']=ThisTime
		elif PortNameOID in thisoid:
			if Index in PortFlow.keys():
				PortFlow[Index]['PortName']=thisvalue
			#PortName=" ".join(thisline[3:])
			#PortName=PortName.strip('"')
			#PortFlow[Index]['PortName']=PortName
		elif BandWidthOID in thisoid:
			#BandWidth=" ".join(thisline[3:])
			#BandWidth=int(BandWidth)
			#Index=thisline[0].split(".")[-1]
			if Index in PortFlow.keys():
				PortFlow[Index]['BandWidth']=thisvalue
		elif InOctetsOID in thisoid:
			#InOctets=" ".join(thisline[3:])
			#InOctets=int(InOctets)
			InOctets=int(thisvalue)
			#Index=thisline[0].split(".")[-1]
			if Index in PortFlow.keys():
				PortFlow[Index]['InOctets']=InOctets
				if PortFlow[Index]['LastInOctets'] == -1:
					PortFlow[Index]['LastInOctets']=PortFlow[Index]['InOctets']
				elif PortFlow[Index]['BandWidth']==0:
					PortFlow[Index]['InUse']=0.0
				else:
					PortFlow[Index]['InUse']=(PortFlow[Index]['InOctets']-PortFlow[Index]['LastInOctets'])/Interval/PortFlow[Index]['BandWidth']*100
					PortFlow[Index]['LastInOctets']=PortFlow[Index]['InOctets']
		elif OutOctetsOID in thisoid:
			#OutOctets=" ".join(thisline[3:])
			#OutOctets=int(OutOctets)
			OutOctets=int(thisvalue)
			#Index=thisline[0].split(".")[-1]
			if Index in PortFlow.keys():
				PortFlow[Index]['OutOctets']=OutOctets
				if PortFlow[Index]['LastOutOctets'] == -1:
					PortFlow[Index]['LastOutOctets']=PortFlow[Index]['OutOctets']
				elif PortFlow[Index]['BandWidth']==0:
					PortFlow[Index]['OutUse']=0.0
				else:
					PortFlow[Index]['OutUse']=(PortFlow[Index]['OutOctets']-PortFlow[Index]['LastOutOctets'])/Interval/PortFlow[Index]['BandWidth']*100
					PortFlow[Index]['LastOutOctets']=PortFlow[Index]['OutOctets']

	print PortFlow
	#time.sleep(10000)

	#数据入库
	#{'56': {'BandWidth': 0, 'OutUse': 0.0, 'Time': 0, 'LastOutOctets': -1, 'PortName': 0, 'LastInOctets': -1, 
	#'InUse': 0.0, 'InOctets': -1, 'OutOctets': -1},{}}
	for key,value in PortFlow.items():
		expr={'DeviceName':DeviceName,'PortName':value['PortName']}
		datas=value
		#print key,expr
		counts=db.queryData_count(net_port_table,expr)
		if counts==0:
			db.insertDatas(net_port_table,datas)
		else:
			db.updateData(net_port_table,expr,datas)
		
		#db.insertDatas(net_port_table_his,expr,datas)

if __name__ == "__main__":


	lchome=lc_libs.lc_getlchome()
	scname=sys.argv[0].split('.')[0]
	logfilename=lchome+'/log/'+scname+'.log'
	confname=lchome+'/conf/'+scname+'.conf'
	
	today=time.strftime('%Y%m%d',time.localtime())
	os.system("mv %s %s.%s" % (logfilename,logfilename,today))
	
	logfile=file(logfilename,'a')
	logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
	logfile.write(logdate+" Started.\n")
	logfile.flush()
	
	agent_hostname=lc_libs.lc_gethostname()
	

	try:
		#初始化数据库
		
		db=lc_libs.lc_mongodb_operater('127.0.0.1',27017)

		db.connect()
		Conn=db.getConn()
		if Conn==None:
			print "Can not Connect to the MondbDB"
			exit(0)
		
		events_dbname='lc_events'
		events_tablename='lc_events'
		
		history_dbname='lc_history'
		history_tablename="lc_process"
		
		events_db=db.useDatabase(events_dbname)
		events_table=db.UseCollection(events_db,events_tablename)
		
		history_db=db.useDatabase(history_dbname)
		history_table=db.UseCollection(history_db,history_tablename)

		net_dbname='lc_net'
		net_port_tablename='lc_net_port'
		net_port_tablename_his='lc_net_port_his'
		
		net_db=db.useDatabase(net_dbname)
		net_port_table=db.UseCollection(net_db,net_port_tablename)
		net_port_table_his=db.UseCollection(net_db,net_port_tablename_his)
		
	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" 初始化数据库失败:\n"+excinfo+"\n")
		logfile.flush()
		exit(0)

	#主程序
	MonitorList = []
	
	for lines in open(confname):
		if lines[0] == '#' or lines.split("\t")[0] not in (agent_hostname,'default'):
			continue

		line=lines.strip('\r\n').split('\t')
		dconf={}
		
		dconf['Hostname']=line[0]
		dconf['DeviceName']=line[1]
		dconf['IPADDR']=line[2]
		dconf['PORT']=line[3]
		dconf['Community']=line[4]
		dconf['Version']=line[5]
		dconf['OID']=line[6]
		dconf['Interval']=line[7]
		dconf['Schedule']=line[8]
		dconf['Holiday']=line[9]
	
		MonitorList.append(dconf)

	usedtime=0
	
	while True:
		time.sleep(1)
		realtime=int(time.time())
		
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		holiday_state = lc_libs.lc_isholiday()
		
		threads = []
		for i in MonitorList:
			if int(i['Holiday']) == 1 and holiday_state == True:
				continue
				
			time_state = lc_libs.lc_schedule(i['Schedule'])
			if time_state == False:
				continue
			
			flag=realtime%int(i['Interval'])
			#print flag
			if flag<=usedtime:
				#print i
				t = threading.Thread(target=func,args=(i,))
				threads.append(t)
		
		for t in threads:
			t.start()
			time.sleep(0.1)
			while True:
				#print len(threading.enumerate())
				time.sleep(0.01)
				if(len(threading.enumerate()) < 100):
					break

		#排除执行程序导致的时间差
		usedtime=int(time.time())-realtime
		#print "usedtime:%s" % usedtime
